package cn.trip.biz.service.impl;

import cn.itrip.beans.dto.Dto;
import cn.itrip.beans.pojo.ItripComment;
import cn.itrip.beans.pojo.ItripHotelOrder;
import cn.itrip.beans.pojo.ItripImage;
import cn.itrip.beans.pojo.ItripUser;
import cn.itrip.beans.vo.ItripCommentAddVO;
import cn.itrip.beans.vo.ItripListCommentVO;
import cn.itrip.common.Page;
import cn.itrip.common.RedisUtil;
import cn.itrip.common.SFTPUtil;
import cn.itrip.dao.ItripCommentMapper;
import cn.itrip.dao.ItripHotelOrderMapper;
import cn.itrip.dao.ItripHotelRoomMapper;
import cn.itrip.dao.ItripImageMapper;
import cn.trip.biz.service.ItripCommentService;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.*;

@Transactional
@Service("itripCommentService")
public class ItripCommentServiceImpl implements ItripCommentService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ItripCommentMapper itripCommentMapper;
    @Autowired
    private ItripImageMapper itripImageMapper;
    @Autowired
    private ItripHotelOrderMapper itripHotelOrderMapper;

    /**
     * 上传图片
     *
     * @param request
     * @return
     */
    @Override
    public Dto<Object> uploadFile(HttpServletRequest request) {
        Dto<Object> dto = new Dto<>();
        List<String> dataList = new ArrayList<>();
        //创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            //转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            int fileCount = 0;
            try {
                fileCount = multiRequest.getFileMap().size();
            } catch (Exception e) {
                fileCount = 0;
                dto.setSuccess("false");
                dto.setMsg("文件太大了");
            }

            if (fileCount > 0 && fileCount <= 4) {
                String token = multiRequest.getHeader("token");
                ItripUser itripUser = (ItripUser) redisUtil.get(token);
                if (null != itripUser) {
                    //取得request中的所有文件名
                    Iterator<String> iter = multiRequest.getFileNames();
                    while (iter.hasNext()) {
                        try {
                            //取得上传文件
                            MultipartFile file = multiRequest.getFile(iter.next());
                            if (file != null) {
                                //取得当前上传文件的文件名称
                                String myFileName = file.getOriginalFilename();
                                //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                                if (myFileName.trim() != "" && (
                                        myFileName.toLowerCase().contains(".jpg")
                                                || myFileName.toLowerCase().contains(".jpeg")
                                                || myFileName.toLowerCase().contains(".png"))) {
                                    //重命名
                                    String suffixString = myFileName.substring(file.getOriginalFilename().indexOf("."));
                                    String fileName = itripUser.getId() + "-" + System.currentTimeMillis() + "-" + ((int) (Math.random() * 10000000)) + suffixString;

                                    SFTPUtil sftp = new SFTPUtil("root", "123456", "172.20.10.2");
                                    sftp.login();

                                    CommonsMultipartFile cFile = (CommonsMultipartFile) file;
                                    DiskFileItem fileItem = (DiskFileItem) cFile.getFileItem();
                                    InputStream inputStream = fileItem.getInputStream();

                                    sftp.upload("/data/itrip/images/comment", fileName, inputStream);
                                    sftp.logout();
                                    dataList.add("http://172.20.10.2/comment/" + fileName);
                                }
                            }
                        } catch (Exception e) {
                            continue;
                        }
                    }
                    dto.setSuccess("true");
                    dto.setErrorCode("0");
                    dto.setData(dataList);
                } else {
                    dto.setSuccess("false");
                    dto.setMsg("文件上传失败");
                }
            } else {
                dto.setSuccess("false");
                dto.setMsg("上传数量受限");
            }
        } else {
            dto.setSuccess("false");
            dto.setMsg("上传的图片类型必须是jpg,jpeg,png");
        }
        return dto;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Dto doAddComment(Map<String, Object> map) {
        map.put("creationDate", new Date());
        Dto dto = new Dto();
        //添加评论
        ItripCommentAddVO itripCommentAddVO = (ItripCommentAddVO) map.get("itripCommentAddVO");
        int result = itripCommentMapper.insertSelective(map);
        if (result > 0) {
            //订单状态变成以点评
            ItripHotelOrder itripHotelOrder = new ItripHotelOrder();
            itripHotelOrder.setId(itripCommentAddVO.getOrderId());
            itripHotelOrder.setOrderStatus(4);
            itripHotelOrderMapper.updateByPrimaryKeySelective(itripHotelOrder);
            boolean temp = true;
            //添加评论图片

            if (itripCommentAddVO.getItripImages() != null) {
                //获取新增评论的commentId
                ItripComment itripComment = itripCommentMapper.getNewComment(map);
                for (int i = 0; i < itripCommentAddVO.getItripImages().length; i++) {
                    ItripImage itripImage = itripCommentAddVO.getItripImages()[i];
                    itripImage.setType("2");
                    itripImage.setCreationDate(new Date());
                    itripImage.setCreatedBy(((ItripUser) map.get("itripUser")).getId());
                    itripImage.setPosition(i);
                    itripImage.setTargetId(itripComment.getId());
                    int result2 = itripImageMapper.insertSelective(itripImage);
                    if (result2 == 0) {
                        temp = false;
                        break;
                    }
                }
            }
            if (temp) {
                dto.setSuccess("true");
                dto.setErrorCode("0");
                if (redisUtil.hasPreKey("hotelComment:*")) {
                    redisUtil.deletePrefix("hotelComment:*");
                }
                if (redisUtil.hasPreKey("hotelCommentCount:*")) {
                    redisUtil.deletePrefix("hotelCommentCount:*");
                }
                if (redisUtil.hasPreKey("hotelCommentScore:*")) {
                    redisUtil.deletePrefix("hotelCommentScore:*");
                }
                if (redisUtil.hasPreKey("hotelComment:*")) {
                    redisUtil.deletePrefix("hotelComment:*");
                }
                if (redisUtil.hasPreKey("hotelCommentCount:*")) {
                    redisUtil.deletePrefix("hotelCommentCount:*");
                }
                if (redisUtil.hasPreKey("hotelCommentScore:*")) {
                    redisUtil.deletePrefix("hotelCommentScore:*");
                }
                if (redisUtil.hasPreKey("order:*")) {
                    redisUtil.deletePrefix("order:*");
                }
                if (redisUtil.hasPreKey("count:*")) {
                    redisUtil.deletePrefix("count:*");
                }

            } else {
                dto.setSuccess("false");
                dto.setMsg("评论图片添加失败");
            }
        } else {
            dto.setSuccess("false");
            dto.setMsg("评论添加失败");
        }
        return dto;
    }

    /**
     * redisKey hotelComment:hotelId
     *
     * @param itripComment
     * @return
     */
    @Override
    public Dto<Page<ItripListCommentVO>> getCommentList(ItripComment itripComment) {
        List<ItripListCommentVO> list = null;
        Dto<Page<ItripListCommentVO>> dto = new Dto<>();
        StringBuffer key = new StringBuffer("hotelComment:" + itripComment.getHotelId());
        if (itripComment.getIsHavingImg() == -1) {
            itripComment.setIsHavingImg(null);
        } else {
            key.append("isHavingImg=" + itripComment.getIsHavingImg());
        }
        if (itripComment.getIsOk() == -1) {
            itripComment.setIsOk(null);
        } else {
            key.append("isOk=" + itripComment.getIsOk());
        }

        List<ItripListCommentVO> comment = new ArrayList<>();
        if (redisUtil.hasKey(key.toString())) {
            list = (List<ItripListCommentVO>) redisUtil.get(key.toString());
        } else {
            list = itripCommentMapper.selectByHotelId(itripComment);
        }
        if (list != null) {
            redisUtil.set(key.toString(), list, 600);
            for (int i = itripComment.getPageNo(); i < (itripComment.getPageNo() + itripComment.getPageSize()); i++) {
                if (i < list.size()) {
                    comment.add(list.get(i));
                }
            }
        }
        int totalCount = selectCount(itripComment);
        Page page = new Page();
        //集合
        page.setRows(comment);
        //一页几条
        page.setPageSize(itripComment.getPageSize());
        //当前页
        page.setCurPage((itripComment.getPageNo() / itripComment.getPageSize()) + 1);
        //总条数
        page.setTotal(totalCount);
        dto.setSuccess("true");
        dto.setErrorCode("0");
        dto.setData(page);
        return dto;
    }

    /**
     * redisKey hotelCommentCount: + HotelId
     *
     * @param itripComment
     * @return
     */
    @Override
    public Integer selectCount(ItripComment itripComment) {
        StringBuffer key = new StringBuffer("hotelCommentCount:" + itripComment.getHotelId());
        if (itripComment.getIsHavingImg() != null && itripComment.getIsHavingImg() == -1) {
            itripComment.setIsHavingImg(null);
        } else {
            key.append("isHavingImg=" + itripComment.getIsHavingImg());
        }
        if (itripComment.getIsOk() != null && itripComment.getIsOk() == -1) {
            itripComment.setIsOk(null);
        } else {
            key.append("isOk=" + itripComment.getIsOk());
        }

        Integer integer = null;
        if (redisUtil.hasKey(key.toString())) {
            integer = (Integer) redisUtil.get(key.toString());
        } else {
            integer = itripCommentMapper.selectCount(itripComment);
            redisUtil.set(key.toString(), integer, 600);
        }
        return integer;
    }

    @Override
    public Dto count(ItripComment itripComment) {
        Dto dto = new Dto();
        Map<String, Integer> count = new HashMap<String, Integer>();
        int totalCount = selectCount(itripComment);
        if (totalCount >= 0) {
            count.put("allcomment", totalCount);
        } else {
            dto.setSuccess("false");
            dto.setMsg("总评论失败");
            return dto;
        }

        itripComment.setIsOk(1);
        int ok = selectCount(itripComment);
        if (ok >= 0) {
            count.put("isok", ok);
        } else {
            dto.setSuccess("false");
            dto.setMsg("值得推荐评论失败");
            return dto;
        }

        itripComment.setIsOk(0);
        int improve = selectCount(itripComment);
        if (improve >= 0) {
            count.put("improve", improve);
        } else {
            dto.setSuccess("false");
            dto.setMsg("值得推荐评论失败");
            return dto;
        }

        itripComment.setIsHavingImg(1);
        itripComment.setIsOk(null);
        int havingimg = selectCount(itripComment);
        if (havingimg >= 0) {
            count.put("havingimg", havingimg);
        } else {
            dto.setSuccess("false");
            dto.setMsg("有图片评论失败");
            return dto;
        }
        dto.setSuccess("true");
        dto.setErrorCode("0");
        dto.setData(count);
        return dto;
    }

    /**
     * redisKey hotelCommentScore: + hotelId
     *
     * @param hotelId
     * @return
     */
    @Override
    public Dto getScoreByHotelId(Long hotelId) {
        Dto dto = new Dto();
        String key = "hotelCommentScore:" + hotelId;
        ItripComment itripComment = null;
        Map<String, Object> map = new HashMap();
        if (redisUtil.hasKey(key)) {
            itripComment = (ItripComment) redisUtil.get(key);
        } else {
            itripComment = itripCommentMapper.getScoreByHotelId(hotelId);
            if (itripComment == null) {
                dto.setSuccess("true");
                dto.setErrorCode("0");
                map.put("avgPositionScore", 0);
                map.put("avgFacilitiesScore", 0);
                map.put("avgServiceScore", 0);
                map.put("avgHygieneScore", 0);
                map.put("avgScore", 0);
                dto.setData(map);
                return dto;
            }
        }
        redisUtil.set(key, itripComment, 600);
        dto.setSuccess("true");
        dto.setErrorCode("0");
        map.put("avgPositionScore", itripComment.getPositionScore());
        map.put("avgFacilitiesScore", itripComment.getFacilitiesScore());
        map.put("avgServiceScore", itripComment.getServiceScore());
        map.put("avgHygieneScore", itripComment.getHygieneScore());
        map.put("avgScore", itripComment.getScore());
        dto.setData(map);
        return dto;
    }
}
